#include "determinant.hh"

//linbox
#include "linbox/algorithms/matrix-hom.h"
#include "linbox/solutions/det.h"
#include "linbox/field/PID-integer.h"
#include "linbox/blackbox/blas-blackbox.h"


using namespace LinBox;
using namespace std;

typedef Modular<int> FiniteField;
typedef BlasBlackbox<FiniteField> FiniteFieldMatrix;
typedef PID_integer IntRing;
//Matrix over Z
typedef BlasBlackbox<IntRing> IntMatrix;

using namespace std;

determinant::determinant(vector<string>& args):userModularFunctionInteger(args){
    
    if(args.size() ==0 ) //
        throw "bad user Function argument exception";
    setFile(0); //this will tell the middleware that there is a user input file, so it can proceed to send the files to different machines
   

    ifstream fs(args[0].c_str());

    stringstream stream;
    stream  << fs.rdbuf();
  
    st = new string;
    st->assign(stream.str());

    fs.close();


}
determinant::~determinant(){

    delete st;
}
void determinant::userModularFunction(fixedBitSizeInteger prime){
    
    IntRing ZZ;
    stringstream stream;
    stream << *st;
    MatrixStream<IntRing> ms(ZZ,stream);
    IntMatrix A(ms);



    FiniteField F(prime);

    FiniteFieldMatrix * Ap; 
    //cout << "Matrix is " << A->rowdim() << " by " << A->coldim() << endl;
    MatrixHom::map(Ap, A, F);//reduce the matrix in the FF 
    FiniteField::Element d;
    detin( d, *Ap, Method::BlasElimination());

    delete Ap;

    //store result with other results for serialization.
    storeResult((fixedBitSizeInteger)d, prime);
    
}
